/**
 * 
 * sequalize 拓展方法
 */
module.exports = exports = {}

const _ = require('lodash');

/**
 * 获取传入参数中与当前模型相关的属性，过滤掉其他属性，防止orm报错
 * 
 * @entity {any} entity 
 * @returns 
 */
exports.pick = function (entity) {
    if (!entity) return undefined
    let obj = {}

    for (let prop of this.attributes) {
        if (entity.hasOwnProperty(prop)) {
            obj[prop] = entity[prop]
        }
    }
    return obj;
}

/**
 * 修改实体
 * 
 * @param {any} entity 表实体
 * @returns 变更后的实体
 */
exports.myUpdate = async function (entity) {
    const data = _.pick(entity);

    const pkName = this.primaryKeyField;

    // 获取主键条件
    const where = {};
    where[pkName] = data[pkName];
    // 删除主键数据是因为，它默认生成的update都会更新data里的值来拼接，所以会多个更新主键这种没意义的部分
    delete data[pkName];
    const ret = await this.update(data, {
        where,
    });
    return ret;
}

/**
 *  插入或者修改 使用自带的方法，但是生成的sql语句会生成update主键字段
 * 
 * @param {any} entity 表实体
 * @returns 变更后的实体
 */
exports.myUpsert = async function (entity) {
    const data = _.pick(entity);

    const buildData = this.build(data);
    const ret = await this.upsert(buildData.dataValues);
    return buildData.get({ plain: true });
}

/**
 * 自己实现的插入或者修改
 * 
 * @param {any} entity 表实体
 * @returns 变更后的实体
 */
exports.mySave = async function (entity) {
    const pkName = this.primaryKeyField;
    const isNewRecord = entity[pkName] == null
    if (isNewRecord) {
        delete entity[pkName]
    }
    const buildData = this.build(entity, {
        isNewRecord,
    });
    await buildData.save()
    return buildData.get({ plain: true });
}


/**
 * 分页查询
 * 
 * @param {any} query 查询对象
 * @returns 分页数据集
 */
exports.page = async function (query) {
    let { where, attributes, order = [['created_at', 'desc']], offset = 0, limit = 10 } = query || {}

    //计算offset
    where = this.pickWhere(where)

    const ret = await this.findAndCountAll({
        attributes,
        where,
        order,
        offset,
        limit,
        raw: query.hasOwnProperty('raw') ? query.raw : true,
    });

    return ret;
}
/**
 * 过滤查询条件，得到有效的查询条件
 * 
 * @param {any} where 查询条件 where信息
 * @returns 有效的查询字段
 */
exports.pickWhere = function (where) {
    if (!where) return where
    let newArr = Object.keys(this.attributes).concat('$and', '$or')
    let obj = {}
    for (let key of newArr) {
        if (_.isObject(where[key]) && _.isEmpty(where[key])) {
           continue;
        } else if (where[key] === null || where[key] === undefined || where[key] === '') {
           continue;
        }else{
            obj[key] = where[key]
        }
    }
    return obj;
}

/**
 * 将对象转换成实体查询对象
 * 
 * @param {any} obj 
 */
exports.pickQuery = function (query) {
    let { where, attributes, order = [['created_at', 'desc']] } = query || {}
    if (typeof order === 'string') {
        var arr = order.split(',')
        if (arr.length == 2) {
            order = arr
        } else {
            order = [
                [order, 'desc']
            ]
        }
    }
    where = this.pickWhere(where)
    return { where, attributes, order }
}